package cn.yeyiu.sexyiu.service

import cn.yeyiu.sexyiu.bean.MangaInfo
import cn.yeyiu.sexyiu.bean.VideoInfo
import cn.yeyiu.sexyiu.bean.VideoTypes
import cn.yeyiu.sexyiu.data.VideoConfig
import cn.yeyiu.sexyiu.utils.DataTool
import cn.yeyiu.sexyiu.utils.NetTool
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.util.*

@Service
class VideoService {
    @Autowired
    lateinit var fileService: FileService
    var serialMap: MutableMap<String?, List<String>> = HashMap()
    var animeMap: MutableMap<String, List<VideoInfo>> = HashMap()
    var otherMap: MutableMap<String, List<VideoInfo>> = HashMap()
    //********** anime 相关 **************/
    /**
     * 根据时间获取已有的anime年份分类
     *
     * @param year 年份
     * @return [2015_01...2016_03...]
     */
    fun getAnimeSerialByYear(year: String): List<String> {
        var mYear = year
        return if (serialMap.containsKey(mYear)) {
            serialMap[mYear]!!
        } else {
            val anime_folders = fileService.getFiles(fileService.PATH + VideoConfig.ANIME)
            if ("" == mYear) mYear = "2020"
            val ctgList: MutableList<String> = ArrayList()
            for (folder in anime_folders) {
                if (folder.isDirectory && folder.name.contains(mYear)) {
                    ctgList.add(folder.name)
                }
            }
            serialMap[mYear] = ctgList
            ctgList
        }
    }

    /**
     * 根据月份分类获取月份anime合集
     *
     * @param serial:2020_10
     * @return [video, ...]
     */
    fun getAnimeListBySerial(serial: String): List<VideoInfo> {
        return if (animeMap.containsKey(serial)) {
            animeMap[serial]!!
        } else {
            val videoInfoList: MutableList<VideoInfo> = ArrayList()
            val videos = fileService.listAnimeVideoNames(serial)
            val pictures = fileService.listAnimeImgNames(serial)
            val picTmp: List<String?> = ArrayList(Arrays.asList(*pictures))
            var videoInfo: VideoInfo // 获取子文件
            for (fileName in videos) {
                videoInfo = VideoInfo()
                val title = fileName.substring(0, fileName.lastIndexOf("."))
                videoInfo.title = title
                videoInfo.sexyiuType = VideoConfig.ANIME
                videoInfo.detailType = serial
                videoInfo.videoSrc =
                    "/file/video/" + videoInfo.sexyiuType + "/" + videoInfo.detailType + "/" + NetTool.encodeUrl(
                        fileName
                    )
                // 获取对应图片
                for (i in picTmp.indices) {
                    val picName = picTmp[i]
                    if (fileName.substring(0, fileName.length - 4) == picName!!.substring(0, picName.length - 4)) {
                        videoInfo.picSrc =
                            "/file/img/" + videoInfo.sexyiuType + "/" + videoInfo.detailType + "/" + NetTool.encodeUrl(
                                picName
                            )

                        picTmp.drop(i)
                        break
                    }
                }
                videoInfoList.add(videoInfo)
            }
            animeMap[serial] = videoInfoList
            videoInfoList
        }
    }

    /**
     * 根据关键词获取相关anime
     *
     * @param key
     * @return [video, ...]
     */
    fun searchAnimes(key: String): List<VideoInfo> {
        val videoInfoList: MutableList<VideoInfo> = ArrayList()
        for (year in VideoConfig.ANIME_YEARS) {
            for (ctg in getAnimeSerialByYear(year)) { //2020_01
                for (videoInfo in getAnimeListBySerial(ctg)) { //
                    if (videoInfo.title.contains(key, ignoreCase = true)) {
                        videoInfoList.add(videoInfo)
                    }
                }
            }
        }
        return videoInfoList
    }

    /**
     * 随机获取anime
     *
     * @return video
     */
    private var pointer = 0
    fun randomAnime(): VideoInfo {
        // 年循环，循环之后打乱 月随机但不与上次一样 系列随机
        if (pointer >= 100) {
            pointer = 0
        }
        val year = VideoConfig.ANIME_YEARS[pointer / 5 % VideoConfig.ANIME_YEARS.size]
        // mouth 保证同一年不同月
        val serials = getAnimeSerialByYear(year)
        val serial = serials[pointer % serials.size]
        ++pointer
        // 具体视频月份里面随机
        val animes = getAnimeListBySerial(serial)
        return animes[DataTool.randInt(animes.size)]
    }

    //********** other 相关 ***********/
    fun getOtherVideoList(type: String): List<VideoInfo> {
        if (!VideoTypes.types.contains(type)) {
            return ArrayList()
        }

        return if (otherMap.containsKey(type)) {
            otherMap[type]!!
        } else {
            val videoFolders = fileService.listOtherVideoNames(type)
            val videoInfoList: MutableList<VideoInfo> = ArrayList()
            var videoInfo: VideoInfo
            for (fileName in videoFolders) {
                val title = fileName.substring(0, fileName.lastIndexOf("."))
                videoInfo = VideoInfo()
                videoInfo.sexyiuType = VideoConfig.OTHER
                videoInfo.detailType = type
                videoInfo.title = title
                videoInfo.videoSrc =
                    "/file/video/" + videoInfo.sexyiuType + "/" + videoInfo.detailType + "/" + NetTool.encodeUrl(
                        fileName
                    )

                videoInfo.picSrc =
                    "/file/img/" + videoInfo.sexyiuType + "/" + videoInfo.detailType + "/" + NetTool.encodeUrl(
                        "$title.jpg"
                    )

                videoInfoList.add(videoInfo)
            }
            otherMap[type] = videoInfoList
            videoInfoList
        }
    }

    fun getKeyVideos(key: String, type: String): List<VideoInfo> {
        val videoInfoList: MutableList<VideoInfo> = ArrayList()
        for (videoInfo in getOtherVideoList(type)) {
            if (videoInfo.title.contains(key, ignoreCase = true)) {
                videoInfoList.add(videoInfo)
            }
        }
        return videoInfoList
    }

    // 发牌随机.算法
    private val videoShuffleList: MutableMap<String, List<Int?>?> = HashMap()
    private val video_flag: MutableMap<String, Int> = HashMap()
    fun randomVideo(type: String): VideoInfo {
        val videoInfos = getOtherVideoList(type)
        if (!videoShuffleList.containsKey(type)) {
            videoShuffleList[type] = DataTool.shuffle(videoInfos.size)
        }
        if (!video_flag.containsKey(type)) {
            video_flag[type] = 0
        }
        val flag = video_flag[type]!!
        video_flag[type] = (flag + 1) % videoInfos.size
        return videoInfos[videoShuffleList[type]!![flag]!!]
    }

    //*********** manga 功能**********/
    fun getMangaList(): List<MangaInfo> {
        val mangas = fileService.listMangaNames()
        val mangaInfos: MutableList<MangaInfo> = ArrayList()
        var mangaInfo: MangaInfo

        for (fileName in mangas) {
            mangaInfo = fileService.getMangaInfo(fileName)!!
            mangaInfo.logo = NetTool.buildMangaLogoPath(mangaInfo.title)

            if (mangaInfo.eps == null) {
                continue
            }

            for (ep in mangaInfo.eps!!) {
                ep.picList = ArrayList()
                ep.logo = NetTool.buildLocalMangaEpLogoPath(mangaInfo.title, if (ep.title !is String) {""} else {ep.title!!})
                for (i in 1..ep.count) {
                    ep.picList!!.add(NetTool.buildMangaImgPath(mangaInfo.title, if (ep.title !is String) {""} else {ep.title!!}, i))
                }
            }
            mangaInfos.add(mangaInfo)
        }
        return mangaInfos
    }

    fun getKeyMangas(key: String): List<MangaInfo> {
        val list: MutableList<MangaInfo> = ArrayList()
        for (mangaInfo in getMangaList()) {
            if (mangaInfo.title.contains(key, ignoreCase = true)) {
                list.add(mangaInfo)
            }
        }
        return list
    }

    fun randomManga(): MangaInfo {
        val list = getMangaList()
        return list[DataTool.randInt(list.size)]
    }
}